package com.north.light.musiclibrary.queue;

import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.media.session.MediaSessionCompat;
import android.text.TextUtils;

import com.north.light.musiclibrary.aidl.model.LibPlayMusicSongInfo;
import com.north.light.musiclibrary.bus.LibPlayMusicBus;
import com.north.light.musiclibrary.bus.tags.LibPlayMusicBusTags;
import com.north.light.musiclibrary.bus.tags.LibPlayMusicQueueIndexUpdated;
import com.north.light.musiclibrary.constans.LibPlayMusicPlayMode;
import com.north.light.musiclibrary.helper.LibPlayMusicQueueHelper;
import com.north.light.musiclibrary.utils.LibPlayMusicAlbumArtCache;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 播放列表管理类
 * Playlist management class
 * create by lzx
 * time:2018/10/30
 */
public class LibPlayMusicPlayQueueManager implements LibPlayMusicIPlayQueue {

    private ArrayList<LibPlayMusicSongInfo> normalPlayList = new ArrayList<>();
    private ArrayList<LibPlayMusicSongInfo> randomPlayList = new ArrayList<>();
    private int mCurrentIndex;
    private Context mContext;

    public LibPlayMusicPlayQueueManager(Context context) {
        mContext = context;
    }

    public int getPlayMode() {
        return LibPlayMusicPlayMode.getInstance().getCurrPlayMode(mContext);
    }

    private boolean isRandomMode() {
        return getPlayMode() == LibPlayMusicPlayMode.PLAY_IN_RANDOM;
    }

    public Context getContext() {
        return mContext;
    }

    @Override
    public void setSongInfos(List<LibPlayMusicSongInfo> songInfos, int currentIndex) {
        int index = 0;
        if (currentIndex != -1) {
            index = currentIndex;
        }
        mCurrentIndex = Math.max(index, 0);
        normalPlayList.clear();
        randomPlayList.clear();
        normalPlayList.addAll(songInfos);
        randomPlayList = (ArrayList<LibPlayMusicSongInfo>) normalPlayList.clone();
        Collections.shuffle(randomPlayList);
        //通知播放列表更新了
        List<MediaSessionCompat.QueueItem> queueItems = LibPlayMusicQueueHelper.getQueueItems(getSongInfos());
        LibPlayMusicBus.getInstance().post(queueItems, LibPlayMusicBusTags.onQueueUpdated);
    }

    @Override
    public void setSongInfos(List<LibPlayMusicSongInfo> songInfos) {
        setSongInfos(songInfos, -1);
    }

    @Override
    public List<LibPlayMusicSongInfo> getSongInfos() {
        if (isRandomMode()) {
            return randomPlayList;
        } else {
            return normalPlayList;
        }
    }

    @Override
    public int getCurrentIndex() {
        return mCurrentIndex;
    }

    @Override
    public void addSongInfo(LibPlayMusicSongInfo songInfo) {
        if (songInfo == null) {
            return;
        }
        if (normalPlayList.contains(songInfo)) {
            return;
        }
        normalPlayList.add(songInfo);
        randomPlayList = (ArrayList<LibPlayMusicSongInfo>) normalPlayList.clone();
        Collections.shuffle(randomPlayList);
        //通知播放列表更新了
        List<MediaSessionCompat.QueueItem> queueItems = LibPlayMusicQueueHelper.getQueueItems(getSongInfos());
        LibPlayMusicBus.getInstance().post(queueItems, LibPlayMusicBusTags.onQueueUpdated);
    }

    @Override
    public void deleteSongInfo(LibPlayMusicSongInfo songInfo, boolean isNeedToPlayNext) {
        if (songInfo == null) {
            return;
        }
        if (normalPlayList.size() == 0 || !normalPlayList.contains(songInfo)) {
            return;
        }
        normalPlayList.remove(songInfo);
        randomPlayList = (ArrayList<LibPlayMusicSongInfo>) normalPlayList.clone();
        Collections.shuffle(randomPlayList);
        //通知播放列表更新了
        List<MediaSessionCompat.QueueItem> queueItems = LibPlayMusicQueueHelper.getQueueItems(getSongInfos());
        LibPlayMusicBus.getInstance().post(queueItems, LibPlayMusicBusTags.onQueueUpdated);
    }

    /**
     * 设置当前的音乐item，用于播放
     */
    public void setCurrentQueueItem(String musicId, boolean isJustPlay, boolean isSwitchMusic) {
        int index = LibPlayMusicQueueHelper.getMusicIndexOnQueue(getSongInfos(), musicId);
        setCurrentQueueIndex(index, isJustPlay, isSwitchMusic);
    }

    /**
     * 设置当前的音乐item，用于播放
     */
    private void setCurrentQueueIndex(int index, boolean isJustPlay, boolean isSwitchMusic) {
        if (index >= 0 && index < getSongInfos().size()) {
            mCurrentIndex = index;
            LibPlayMusicQueueIndexUpdated updated = new LibPlayMusicQueueIndexUpdated(mCurrentIndex, isJustPlay, isSwitchMusic);
            LibPlayMusicBus.getInstance().post(updated, LibPlayMusicBusTags.onCurrentQueueIndexUpdated);
        }
    }

    @Override
    public int getSongInfosSize() {
        return normalPlayList.size();
    }

    @Override
    public LibPlayMusicSongInfo getCurrentSongInfo() {
        if (!LibPlayMusicQueueHelper.isIndexPlayable(mCurrentIndex, normalPlayList) || !LibPlayMusicQueueHelper.isIndexPlayable(mCurrentIndex, randomPlayList)) {
            return null;
        }
        if (isRandomMode()) {
            return randomPlayList.get(mCurrentIndex);
        } else {
            return normalPlayList.get(mCurrentIndex);
        }
    }

    @Override
    public void setCurrentSong(int currentIndex) {
        if (normalPlayList.size() == 0) {
            return;
        }
        if (!LibPlayMusicQueueHelper.isIndexPlayable(currentIndex, normalPlayList)) {
            return;
        }
        this.mCurrentIndex = currentIndex;
    }

    @Override
    public void setCurrentSong(LibPlayMusicSongInfo songInfo) {
        if (normalPlayList.size() == 0 || songInfo == null) {
            return;
        }
        int index = LibPlayMusicQueueHelper.getMusicIndexOnQueue(getSongInfos(), songInfo.getSongId());
        if (index != -1) {
            mCurrentIndex = index;
        }
    }

    @Override
    public void updateSongCoverBitmap(String musicId, Bitmap bitmap) {
        LibPlayMusicSongInfo musicInfo = LibPlayMusicQueueHelper.getMusicInfoById(getSongInfos(), musicId);
        if (musicInfo == null) {
            return;
        }
        musicInfo.setSongCoverBitmap(bitmap);
        int index = getSongInfos().indexOf(musicInfo);
        if (isRandomMode()) {
            randomPlayList.set(index, musicInfo);
        } else {
            normalPlayList.set(index, musicInfo);
        }
    }

    @Override
    public LibPlayMusicSongInfo getPreMusicInfo(boolean isUpdateIndex) {
        return getNextOrPreMusicInfo(-1, isUpdateIndex);
    }

    @Override
    public LibPlayMusicSongInfo getNextMusicInfo(boolean isUpdateIndex) {
        return getNextOrPreMusicInfo(1, isUpdateIndex);
    }

    @Override
    public boolean hasNextSong() {
        if (getPlayMode() == LibPlayMusicPlayMode.PLAY_IN_ORDER) {
            return mCurrentIndex != getSongInfosSize() - 1;
        } else {
            return getSongInfosSize() > 1;
        }
    }

    @Override
    public boolean hasPreSong() {
        if (getPlayMode() == LibPlayMusicPlayMode.PLAY_IN_ORDER) {
            return mCurrentIndex != 0;
        } else {
            return getSongInfosSize() > 1;
        }
    }

    /**
     * 上一首或下一首
     */
    private LibPlayMusicSongInfo getNextOrPreMusicInfo(int amount, boolean isUpdateIndex) {
        LibPlayMusicSongInfo info = null;
        int playMode = getPlayMode();
        if (playMode == LibPlayMusicPlayMode.PLAY_IN_RANDOM || playMode == LibPlayMusicPlayMode.PLAY_IN_FLASHBACK || playMode == LibPlayMusicPlayMode.PLAY_IN_LIST_LOOP) {
            if (skipQueuePosition(amount, isUpdateIndex)) {
                info = getCurrentSongInfo();
            }
        } else if (playMode == LibPlayMusicPlayMode.PLAY_IN_SINGLE_LOOP || playMode == LibPlayMusicPlayMode.PLAY_IN_ORDER) {
            if (hasNextSong() && skipQueuePosition(amount, isUpdateIndex) || hasPreSong() && skipQueuePosition(amount, isUpdateIndex)) {
                info = getCurrentSongInfo();
            }
        }
        return info;
    }

    @Override
    public void updateMetadata() {
        LibPlayMusicSongInfo currentMusic = getCurrentSongInfo();
        if (currentMusic == null) {
            LibPlayMusicBus.getInstance().post("", LibPlayMusicBusTags.onMetadataRetrieveError);
            return;
        }
        final String musicId = currentMusic.getSongId();
        LibPlayMusicSongInfo metadata = LibPlayMusicQueueHelper.getMusicInfoById(getSongInfos(), musicId);
        if (metadata == null) {
            throw new IllegalArgumentException("Invalid musicId " + musicId);
        }
        if (!TextUtils.isEmpty(metadata.getSongCover())) {
            String coverUri = metadata.getSongCover();
            //获取图片bitmap
            LibPlayMusicAlbumArtCache.getInstance().fetch(coverUri, new LibPlayMusicAlbumArtCache.FetchListener() {
                @Override
                public void onFetched(String artUrl, Bitmap bitmap, Bitmap icon) {
                    updateSongCoverBitmap(musicId, bitmap);
                    LibPlayMusicSongInfo currentMusic = getCurrentSongInfo();
                    if (currentMusic == null) {
                        return;
                    }
                    String currentPlayingId = currentMusic.getSongId();
                    if (musicId.equals(currentPlayingId)) {

                        LibPlayMusicSongInfo songInfo = LibPlayMusicQueueHelper.getMusicInfoById(getSongInfos(), currentPlayingId);
                        LibPlayMusicBus.getInstance().post(songInfo, LibPlayMusicBusTags.onMetadataChanged);
                    }
                }
            });
        }
    }

    /**
     * 转跳到指定位置
     *
     * @param amount 维度
     * @return boolean
     */
    public boolean skipQueuePosition(int amount, boolean isUpdateIndex) {
        if (getSongInfos().size() == 0) {
            return false;
        } else {
            int index = mCurrentIndex + amount;
            if (index < 0) {
                // 在第一首歌曲是上一首，让你在第一首歌曲上
                int playModel = LibPlayMusicPlayMode.getInstance().getCurrPlayMode(mContext);
                if (playModel == LibPlayMusicPlayMode.PLAY_IN_FLASHBACK || playModel == LibPlayMusicPlayMode.PLAY_IN_LIST_LOOP) { //如果是倒序或者列表循环，则回去最后一首
                    index = getSongInfos().size() - 1;
                } else {
                    index = 0;
                }
            } else {
                //当在最后一首歌时点下一首将返回第一首个
                index %= getSongInfos().size();
            }
            if (!LibPlayMusicQueueHelper.isIndexPlayable(index, getSongInfos())) {
                return false;
            }
            if (isUpdateIndex) {
                mCurrentIndex = index;
            }
            return true;
        }
    }

    /**
     * 检查播放模式改变后下标是否正确
     */
    public void checkIndexForPlayMode(String mCurrentMediaId) {
        int currIndex = LibPlayMusicQueueHelper.getMusicIndexOnQueue(getSongInfos(), mCurrentMediaId);
        if (mCurrentIndex != currIndex) {
            mCurrentIndex = currIndex;
        }
    }
}
